<?php

namespace app\api\logic;

use app\api\service\HelpTaskService;
use app\common\exception\BusinessException;
use app\common\model\HelpTaskItem;
use app\common\model\UserMaterial;
use app\common\service\UserService;

class HelpTask
{
    /**
     * create
     * @param array $param
     * @return int|mixed|string
     * @throws
     */
    public function create(array $param)
    {
        // 提取参数
        $time = time();
        $dataId = trim($param['data_id']);
        $dataType = trim($param['data_type']);
        $userId = $param['userId'];

        // 查询是否已经存在任务
        $where = [
            ['uid', '=', $userId],
            ['data_id', '=', $dataId],
            ['data_type', '=', $dataType],
            ['expire', '>', $time],
        ];
        $model = new \app\common\model\HelpTask();
        $info = $model->where($where)->find();
        if ($info) {
            return $info['id'];
        }

        // 创建任务
        $service = new HelpTaskService();
        $taskConfig = $service->getTypeInfo($dataType);
        $saveData = [
            'uid' => $userId,
            'data_id' => $dataId,
            'data_type' => $dataType,
            'need_count' => $taskConfig['count'],
            'expire' => $time + $taskConfig['expire'] * 86400,
            'a_time' => $time,
            'u_time' => $time,
        ];
        $helpTaskId = $model->insertGetId($saveData);
        if (!$helpTaskId) {
            throw new BusinessException('创建互助任务失败');
        }

        // 返回
        return $helpTaskId;
    }

    /**
     * info
     * @param array $param
     * @return array
     * @throws
     */
    public function info(array $param): array
    {
        // 提取参数
        $id = $param['id'];
        $userId = $param['userId'] ?? 0;

        // 查询数据
        $model = new \app\common\model\HelpTask();
        $info = $model->find($id);
        $info = $info ? $info->toArray() : [];
        if (!$info) {
            throw new BusinessException('数据不存在或已被删除');
        }

        // 填充用户信息
        $userInfo = (new UserService())->getUserById($info['uid']);
        $info['uid_nickname'] = $userInfo['nickname'] ?? '';
        $info['uid_avatar'] = $userInfo['avatar'] ?? '';

        // 填充互助好友信息
        $info['item_list'] = $this->getItemList($info['id'], $userId);

        // 填充任务有效期
        $info['expire_name'] = date('Y-m-d', $info['expire']);

        // 填充任务完成比例
        $info['process_rate'] = 0;
        $info['process_rate_name'] = '0%';
        if ($info['real_count']) {
            $info['process_rate'] = round($info['real_count'] / $info['need_count'], 1);
            $info['process_rate'] = min($info['process_rate'], 1);
            $info['process_rate_name'] = ($info['process_rate'] * 100) . '%';
        }

        // 计算人数差距
        $info['diff_count'] = max($info['need_count'] - $info['real_count'], 0);

        // 根据数据类型查询数据
        $service = new HelpTaskService();
        $info['type_data'] = $service->getTypeData($info['data_id'], $info['data_type']);

        // 当前访客是否用户自己
        $info['view_is_self'] = ($info['uid'] == $userId);

        // 返回
        return $info;
    }

    /**
     * save
     * @param array $param
     * @throws
     */
    public function save(array $param)
    {
        // 提取参数
        $id = $param['id'];
        $userId = $param['userId'] ?? 0;

        // 查询数据
        $taskModel = new \app\common\model\HelpTask();
        $info = $taskModel->find($id);
        if ($info['uid'] != $userId) {
            throw new BusinessException('仅支持本人修改数据');
        }

        // 组装数据
        $saveData = [];
        if (!empty($param['shout'])) {
            $param['shout'] = trim($param['shout']);
            if (mb_strlen($param['shout']) > 20) {
                throw new BusinessException('内容不能超过20个字');
            }
            $saveData['shout'] = $param['shout'];
        }
        if ($saveData) {
            $taskModel = new \app\common\model\HelpTask();
            $isUpdate = $taskModel->save_data($saveData, [['id', '=', $id]]);
            if (!$isUpdate) {
                throw new BusinessException('更新数据失败');
            }
        }
    }

    /**
     * save
     * @param array $param
     * @throws
     */
    public function itemSave(array $param)
    {
        // 提取参数
        $id = $param['id'];
        $userId = $param['userId'] ?? 0;

        // 查询数据
        $taskItemModel = new HelpTaskItem();
        $info = $taskItemModel->find($id);
        //var_dump($userId,$info);
        if ($info['uid'] != $userId) {
            throw new BusinessException('仅支持本人修改数据');
        }

        // 组装数据
        $saveData = [];
        if (!empty($param['message'])) {
            $param['message'] = trim($param['message']);
            if (mb_strlen($param['message']) > 15) {
                throw new BusinessException('内容不能超过15个字');
            }
            $saveData['message'] = $param['message'];
        }
        if ($saveData) {
            $isUpdate = $taskItemModel->save_data($saveData, [['id', '=', $id]]);
            if (!$isUpdate) {
                throw new BusinessException('更新数据失败');
            }
        }
    }

    /**
     * getItemListByPid
     * @param int $pid
     * @param int $userId
     * @return array
     */
    private function getItemList(int $pid, int $userId): array
    {
        // 查询条件
        $model = new HelpTaskItem();
        $where = [
            'pid' => $pid
        ];

        // 查询数据
        $itemList = $model->where($where)->select();
        $itemList = $itemList ? $itemList->toArray() : [];

        // 提取全部Uid
        $allUid = array_column($itemList, 'uid');
        if ($allUid) {
            $where = [
                ['id', 'in', $allUid]
            ];
            $field = 'id,avatar,nickname';
            $userDict = (new \app\admin\model\user\User())->where($where)->column($field, 'id');
        }

        // 填充数据
        foreach ($itemList as $key => $val) {
            // 提取参数
            $uid = $val['uid'];

            // 当前访客是否用户自己
            $itemList[$key]['view_is_self'] = ($uid == $userId);

            // 填充用户信息
            $itemList[$key]['avatar'] = $userDict[$uid]['avatar'] ?? '';
            $itemList[$key]['nickname'] = $userDict[$uid]['nickname'] ?? '';

            // 格式化时间
            $itemList[$key]['time_text'] = beautifyTime(strtotime($val['a_time']));
        }

        // 返回
        return $itemList;
    }

    /**
     * grab
     * @param array $param
     * @throws
     */
    public function grab(array $param)
    {
        // 提取参数
        $id = $param['id'];
        $userId = $param['userId'];
        $message = $param['message'] ?? '';

        // 查询数据
        $taskModel = new \app\common\model\HelpTask();
        $info = $taskModel->find($id);
        $info = $info ? $info->toArray() : [];
        if (!$info) {
            throw new BusinessException('数据不存在或已被删除');
        }
        if ($info['uid'] == $userId) {
            //throw new BusinessException('不支持给自己助力喔');
        }

        // 查询当前用户是否已经帮过别人
        $where = [
            'uid' => $userId,
        ];
        $itemModel = new HelpTaskItem();
        $count = $itemModel->where($where)->count();
        if ($count) {
            //throw new BusinessException('您已经参与过相同活动');
        }

        // 开启事务
        $taskModel->startTrans();

        // 保存助力记录
        $isAdd = $itemModel->add_data([
            'pid' => $id,
            'uid' => $userId,
            'message' => $message,
        ]);
        if (!$isAdd) {
            throw new BusinessException('保存助力记录失败');
        }

        // 查询助力记录总数
        $count = $itemModel->where(['pid' => $id])->count();

        // 更新主任务
        $isPass = $count >= $info['need_count'];
        $saveData = [
            'real_count' => $count,
            'status' => $isPass ? 2 : 1,
        ];
        $isSaved = $taskModel->save_data($saveData, ['id' => $id]);
        if (!$isSaved) {
            throw new BusinessException('更新助力任务失败');
        }

        // 如果达标则赠送资料
        if ($isPass) {
            // 赠送资料
            $expire = 86400 * $info['expire'];
            (new UserMaterial())->setExpire($userId, $id, $expire);
        }

        // 提交事务
        $taskModel->commit();
    }
}